package site.beanyon.now.aspect.log;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import site.beanyon.now.model.po.TimeSpanPO;
import site.beanyon.now.service.UserService;

/**
 * 时间区间日志切面
 */
@Aspect
@Component
class TimeSpanLogAspect {
    private Logger logger = LoggerFactory.getLogger(TimeSpanLogAspect.class);

    @Autowired
    private UserService userService;

    /**
     * 创建时间区间环绕通知
     *
     * @param jp 连接点
     * @return 是否创建成功
     */
    @Around("execution(* site.beanyon.now.service.TimeSpanService.createTimeSpan(..))")
    private boolean createTimeSpan(ProceedingJoinPoint jp) throws Throwable {
        // 创建前
        Integer userId = this.userService.getCurrentUser().getId();
        TimeSpanPO timeSpanPO = (TimeSpanPO) jp.getArgs()[0];

        boolean result = false;

        try {
            // 创建时间区间
            result = (boolean) jp.proceed();
        } catch (Throwable throwable) {
            // 创建异常
            logger.error("[error] create time span, user_id=" + userId
                    + ", card_id=" + timeSpanPO.getCardId()
                    + ", start_time=" + timeSpanPO.getStartTime());
            throw throwable;
        }

        // 创建后
        logger.info("[success] create time span, user_id=" + userId
                + ", card_id=" + timeSpanPO.getCardId()
                + ", start_time=" + timeSpanPO.getStartTime());

        return result;
    }

    /**
     * 更新开始时间方法环绕通知
     *
     * @param jp 连接点
     * @return 是否更新成功
     */
    @Around("execution(* site.beanyon.now.service.TimeSpanService.updateStartTime(..))")
    private boolean updateStartTime(ProceedingJoinPoint jp) throws Throwable {
        // 更新前
        Integer userId = this.userService.getCurrentUser().getId();
        Integer spanId = (Integer) jp.getArgs()[0];
        Long startTime = (Long) jp.getArgs()[1];

        boolean result = false;

        try {
            // 执行更新
            result = (boolean) jp.proceed();
        } catch (Throwable throwable) {
            // 更新异常
            logger.error("[error] update time span start_time, user_id=" + userId
                    + ", span_id=" + spanId
                    + ", start_time=" + startTime);
            throw throwable;
        }

        // 更新后
        logger.info("[success] update time span start_time, user_id=" + userId
                + ", span_id=" + spanId
                + ", start_time=" + startTime);

        return result;
    }

    /**
     * 更新结束时间方法环绕通知
     *
     * @param jp 连接点
     * @return 是否更新成功
     */
    @Around("execution(* site.beanyon.now.service.TimeSpanService.updateEndTime(..))")
    private boolean updateEndTime(ProceedingJoinPoint jp) throws Throwable {
        // 更新前
        Integer userId = this.userService.getCurrentUser().getId();
        Integer spanId = (Integer) jp.getArgs()[0];
        Long endTime = (Long) jp.getArgs()[1];

        boolean result = false;

        try {
            // 执行更新
            result = (boolean) jp.proceed();
        } catch (Throwable throwable) {
            // 更新异常
            logger.error("[error] update time span end_time, user_id=" + userId
                    + ", span_id=" + spanId
                    + ", end_time=" + endTime);
            throw throwable;
        }

        // 更新后
        logger.info("[success] update time span end_time, user_id=" + userId
                + ", span_id=" + spanId
                + ", end_time=" + endTime);

        return result;
    }
}
